package com.budwk.app.sqfwV2.generator.dayingRoadExcel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.component.CommonComponent;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.bo.SqfwExcelJudgeRes;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseExcelParamDTO;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwV2.component.DayingRoadPdfComponent;
import com.budwk.app.sqfwV2.dto.dto.FireSafetyOnDayingRoadPdfDTO;
import com.budwk.app.sqfwV2.dto.dto.centuryCity.SafeCheckTaskParamDataDTO;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.AccommodatePeopleVo;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.SandwichingVo;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.template.GasSafetyWeeklyExcelVo;
import com.budwk.app.sqfwV2.dto.image.FireSafetyOnDayingRoadExcelImageConfigBO;
import com.budwk.app.sqfwV2.enums.DayingRoadFileServiceEnum;
import com.budwk.app.sqfwV2.enums.RectificateTimeEnum;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.excelPictureConfigBO.ExcelFileCreateParamBO;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 9 附件1：燃气安全排查统计周报表/Excel
 */

@Slf4j
public class GasSafetyWeeklyGenerator extends BaseTemplateExcelGenerator implements DayingRoadExcelGenerator {

    @Override
    protected String getTemplateName() {
        return DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_REPORT.getFilePath();
    }

    /**
    * 可以参照 {@link com.budwk.app.sqfw.enums.DownLoadFileNameEnum}
    *
    * @return 文件名名称
    */
    @Override
    public String getDownloadFileName() {
        //TODO 在这里返回你生成的文件名名称，注意注意注意不用带上后缀
        return DayingRoadPdfComponent.getDictName(DayingRoadFileServiceEnum.DAYING_ROAD_EXCEL_REPORT.getCode(), null);
    }

    /**
     * 用户自定义excel基础参数，比如表头这样的公用数据
     * @param excelParam 已经填充的基础数据据
     * @param excelCreateParam excel生成提供的原料
     */
    @Override
    protected void customerPopularSheetBaseParam(Map<String, Object> excelParam, SqfwExcelCreateCommonBO excelCreateParam) {
        BaseExcelParamDTO b = excelCreateParam.getBaseExcelParamDTO();
        excelParam.put("areaLevel", StrUtil.formatStr(b.getDistrict()));
        SysUserService userService = NutzIocUtils.getBean(SysUserService.class);
        Sys_user user = userService.fetch(b.getCreateUserId());
        excelParam.put("unitName", DayingRoadPdfComponent.getUnitName(b));
        excelParam.put("createUsernamePhone", b.getCreateUserName() + " " + user.getMobile());

    }

    // 组装map
    @Override
    protected void customerPopularSheetDataParam(List<Map<String, Object>> listMap, SqfwExcelCreateCommonBO excelCreateParam) {
        log.info("GasSafetyWeeklyGenerator customerPopularSheetDataParam listMap: {}", JSONObject.toJSONString(listMap));
        List<Sqfw_formSummary_new> formSummaryNews = DayingRoadPdfComponent.getSummaryList(listMap, excelCreateParam);
        List<String> removeIds = new ArrayList<>();
        for (Sqfw_formSummary_new formSummaryNew : formSummaryNews) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(formSummaryNew.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            if (!isGenerateExcel(roadPdfDTO)) {
                // 不生成 记录id
                removeIds.add(formSummaryNew.getId());
            }
        }
        if (removeIds.size() > 0) {
            formSummaryNews.removeIf(e -> removeIds.contains(e.getId()));
        }
        if (formSummaryNews.size() == 0) {
            return;
        }
        listMap.add(CommonComponent.entityToMap(buildGasSafetyWeekly(formSummaryNews)));
        log.info("GasSafetyWeeklyGenerator build map end");
    }

    private GasSafetyWeeklyExcelVo buildGasSafetyWeekly(List<Sqfw_formSummary_new> formSummaryNews) {
        List<String> sqfwIds = formSummaryNews.stream().map(Sqfw_formSummary_new::getSqfwId).distinct().collect(Collectors.toList());
        GasSafetyWeeklyExcelVo excelVo = new GasSafetyWeeklyExcelVo();
        excelVo.setStreet(formSummaryNews.get(0).getCounty())
                .setCheckCount(sqfwIds.size());
        // 组织检查人次
        Set<String> checkPersonSet = new HashSet<>(); //组织检查人次
        for (Sqfw_formSummary_new formSummaryNew : formSummaryNews) {
            FireSafetyOnDayingRoadPdfDTO roadPdfDTO = JSONObject.parseObject(formSummaryNew.getParamData(), FireSafetyOnDayingRoadPdfDTO.class);
            String peers = roadPdfDTO.getPeers();
            if (StringUtils.isNotEmpty(peers)) {
                checkPersonSet.addAll(List.of(peers.split(",")));
            }
            if (StringUtils.isNotEmpty(formSummaryNew.getCreateBy())) {
                checkPersonSet.add(formSummaryNew.getCreateBy());
            }
            statisticalHazards(roadPdfDTO, excelVo);
        }
        excelVo.setCheckPersonCount(checkPersonSet.size()).setCompaneyCount(formSummaryNews.size());
        return excelVo;
    }

    // 统计隐患
    private void statisticalHazards(FireSafetyOnDayingRoadPdfDTO roadPdfDTO, GasSafetyWeeklyExcelVo excelVo) {
        // 取出所有隐患的数据 25个问题   夹层楼板 楼层建筑材料 该场所配备灭火器数量 隐患其他问题 电气线路情况 电动车使用情况
        // 明火\高温 是否存放易燃易爆危险品 是否使用黑酒精 燃气报警器的数量 报警器使用是否正常 住人问题
        // 1 25个问题
        LocalDateTime inspectionDate = roadPdfDTO.getInspectionDate();
        String inspectionDateStr = LocalDateTimeUtil.format(inspectionDate, DatePattern.NORM_DATE_PATTERN);
        String todayDate = LocalDateTimeUtil.format(LocalDate.now(), DatePattern.NORM_DATE_PATTERN);
        List<SafeCheckTaskParamDataDTO> others = roadPdfDTO.getOtherPatrolContents();
        for (SafeCheckTaskParamDataDTO other : others) {
            buildDanger(other, inspectionDateStr, todayDate, excelVo);
        }
        // 夹层楼板 楼层建筑材料
        SandwichingVo s = roadPdfDTO.getSandwichConstructionUse();
        if (s != null) {
            buildDanger(s.getMezzaninFfloorSlab(), inspectionDateStr, todayDate, excelVo);
            buildDanger(s.getStaircaseBuildingMaterials(), inspectionDateStr, todayDate, excelVo);
        }
        // 该场所配备灭火器数量
        buildDanger(roadPdfDTO.getWhetherEquippedFire(), inspectionDateStr, todayDate, excelVo);
        // 隐患其他问题 消防设施的其他问题
        buildDanger(roadPdfDTO.getFireOtherIssues(), inspectionDateStr, todayDate, excelVo);
        // 电气线路情况
        buildDanger(roadPdfDTO.getElectricalCircuitSituation(), inspectionDateStr, todayDate, excelVo);
        // 电动车使用情况
        buildDanger(roadPdfDTO.getElectricBicyclesUse(), inspectionDateStr, todayDate, excelVo);
        // 明火\高温
        buildDanger(roadPdfDTO.getFireHighUsageArea(), inspectionDateStr, todayDate, excelVo);
        // 是否存放易燃易爆危险品
        buildDanger(roadPdfDTO.getIsCombustiblEexplosive(), inspectionDateStr, todayDate, excelVo);
        // 是否使用黑酒精 燃气报警器的数量 报警器使用是否正常
        buildDanger(roadPdfDTO.getIsBlackAlcoholUsed(), inspectionDateStr, todayDate, excelVo);
        buildDanger(roadPdfDTO.getGasAlarmsNumber(), inspectionDateStr, todayDate, excelVo);
        buildDanger(roadPdfDTO.getIsAlarmNormal(), inspectionDateStr, todayDate, excelVo);
        // 住人问题
        AccommodatePeopleVo a = roadPdfDTO.getAccommodatePeople();
        if (a != null) {
            SafeCheckTaskParamDataDTO p = new SafeCheckTaskParamDataDTO();
            p.setRectificationTypeCode(a.getRectificateType()).setRiskLevelCode(a.getHazardLevelType());
            buildDanger(p, inspectionDateStr, todayDate, excelVo);
        }
//        // 燃气报警器的数量
//        buildDanger(roadPdfDTO.getGasAlarmsNumber(), inspectionDateStr, todayDate, excelVo);
//        // 报警器使用是否正常
//        buildDanger(roadPdfDTO.getIsAlarmNormal(), inspectionDateStr, todayDate, excelVo);
    }

    private void buildDanger(SafeCheckTaskParamDataDTO p, String inspectionDateStr, String todayDate, GasSafetyWeeklyExcelVo excelVo) {
        if (p == null) {
            return;
        }
        String hazardLevelType = p.getRiskLevelCode();
        if (StringUtils.isEmpty(hazardLevelType)) {
            return;
        }
        if (DictConstants.HAZARD_LEVEL_GENERAL.equals(hazardLevelType)) {
            if (todayDate.equals(inspectionDateStr)) {
                excelVo.setHazardsTotal(excelVo.getHazardsTotal() + 1).setDayTodayCount(excelVo.getDayTodayCount() + 1);
            }
            excelVo.setGeneralTotal(excelVo.getGeneralTotal() + 1);
            if (RectificateTimeEnum.IMMEDIATE_RECTIFICAIOTN.getCode().equals(p.getRectificationTypeCode())) {
                excelVo.setGeneralRectified(excelVo.getGeneralRectified() + 1);
            }
        }
        if (DictConstants.HAZARD_LEVEL_BIG.equals(hazardLevelType)) {
            if (todayDate.equals(inspectionDateStr)) {
                excelVo.setBigDangerTotal(excelVo.getBigDangerTotal() + 1).setDayTodayCount(excelVo.getDayTodayCount() + 1);
            }
            excelVo.setBigTotal(excelVo.getBigTotal() + 1);
            if (RectificateTimeEnum.IMMEDIATE_RECTIFICAIOTN.getCode().equals(p.getRectificationTypeCode())) {
                excelVo.setBigRectified(excelVo.getBigRectified() + 1);
            }
        }
    }

    /**
     * /○如果只有【用电】选项，则不进行计算。
     *         //○如果只有【无】选项，则不进行计算。
     *         //○如果只有【用炭】选项，则不进行计算。
     * @param roadPdfDTO
     */
    public boolean isGenerateExcel(FireSafetyOnDayingRoadPdfDTO roadPdfDTO) {
        // 判断a5是否为重点场所 选择重点场所 不生成表格
        if (DayingRoadPdfComponent.isKeyLocations(roadPdfDTO)) {
            return false;
        }
        String fireAndElectricityUsage = roadPdfDTO.getFireAndElectricityUsage();
        if (StringUtils.isNotEmpty(fireAndElectricityUsage)) {
            // 按照逗号分割
            if (DictConstants.BOTTLED_ETHER_ELECTRICITY.equals(fireAndElectricityUsage)) {
                return false;
            }
            if (DictConstants.BOTTLED_ETHER_ELECTRICITY_NO.equals(fireAndElectricityUsage)) {
                return false;
            }
            if (DictConstants.BOTTLED_ETHER_CHARCOAL.equals(fireAndElectricityUsage)) {
                return false;
            }
        }
        return true;
    }

    @Override
    protected void completeExcelFileCreateParam(ExcelFileCreateParamBO excelFileCreateParam) {

    }

    @Override
    protected void customerPopularRowDataMap(Map<String, Object> rowDataMap, SqfwExcelForSummaryBO forSummaryBO) {

    }

    /**
     * 如果在遍历之前就能够判断excel是否生成，那么就在这个方法中进行判断
     * @param excelCreateParam excel生成所需的最为全面的数据
     * @param excelParam excel已经填充的部分数据
     */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeErgodic(SqfwExcelCreateCommonBO excelCreateParam, Map<String, Object> excelParam) {
        return DayingRoadPdfComponent.getSqfwExcelJudgeRes(excelCreateParam, new GasSafetyWeeklyGenerator());
    }

    /**
    * 如果在遍历之后能够判断excel是否生成，那么就在这个方法中进行判断
    * @param excelParam excel已经填充的部分数据
    */
    @Override
    protected SqfwExcelJudgeRes judgeDataIntoExcelBeforeCreate(Map<String, Object> excelParam) {
        return null;

    }

    @Override
    protected Class<?> getImageConfigBO() {
        return FireSafetyOnDayingRoadExcelImageConfigBO.class;
    }
}
